package com.eco.fanliapp.service.impl;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import cn.afterturn.easypoi.handler.inter.IExcelVerifyHandler;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.response.AlipayFundTransToaccountTransferResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eco.fanliapp.common.constant.NewsEnumLog;
import com.eco.fanliapp.common.response.ServerResponse;
import com.eco.fanliapp.dao.AppOrderDetailMapper;
import com.eco.fanliapp.dao.AppUserMapper;
import com.eco.fanliapp.dao.AppWithdrawalMapper;
import com.eco.fanliapp.entity.*;
import com.eco.fanliapp.service.*;
import com.eco.fanliapp.utils.*;
import com.eco.fanliapp.vo.AppWithdrawalExportVo;
import com.eco.fanliapp.vo.AppWithdrawalOfMode;
import com.eco.fanliapp.vo.WithdrawalInfo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 提现记录 服务层实现
 *
 * @author xiaoxx
 * @date 2019-05-14
 */
@Service
public class AppWithdrawalServiceImpl extends ServiceImpl<AppWithdrawalMapper, AppWithdrawal> implements IAppWithdrawalService {

    private static final Logger log = LoggerFactory.getLogger(AppWithdrawalServiceImpl.class);

    @Autowired
    private AppWithdrawalMapper appWithdrawalMapper;

    @Autowired
    private AppOrderDetailMapper orderDetailMapper;

    @Autowired
    private AppUserMapper userMapper;

    @Autowired
    private IAlipayService iAlipayService;
    @Autowired
    private IAppNewsLogService iAppNewsLogService;

    @Autowired
    private IAppCompanyService appCompanyService;
    @Autowired
    private IAppUserService appUserService;

    @Autowired
    private ISyBlacklistService iSyBlacklistService;

    @Autowired
    private RedisLockService redisLockService;

    @Autowired
    private ISyUserMoneyLogService syUserMoneyLogService;

    @Autowired
    private ISyUserMoneyService iSyUserMoneyService;

    @Autowired
    private IAppWxWithdrawalService iAppWxWithdrawalService;

    @Autowired
    private RedisTemplateService redisTemplateService;
    @Autowired
    private IAppUserOrderService appUserOrderService;

    /**
     * 查询提现记录信息
     *
     * @param id 提现记录ID
     * @return 提现记录信息
     */
    @Override
    public AppWithdrawal selectAppWithdrawalById(Long id) {
        return appWithdrawalMapper.selectAppWithdrawalById(id);
    }

    /**
     * 查询提现记录列表
     *
     * @param appWithdrawal 提现记录信息
     * @return 提现记录集合
     */
    @Override
    public List<AppWithdrawal> selectAppWithdrawalList(AppWithdrawal appWithdrawal) {
        return appWithdrawalMapper.selectAppWithdrawalList(null);
    }

    /**
     * 新增提现记录
     *
     * @param appWithdrawal 提现记录信息
     * @return 结果
     */
    @Override
    @Transactional
    public int insertAppWithdrawal(AppWithdrawal appWithdrawal) {
        return appWithdrawalMapper.insertAppWithdrawal(appWithdrawal);
    }

    /**
     * 修改提现记录
     *
     * @param appWithdrawal 提现记录信息
     * @return 结果
     */
    @Override
    public int updateAppWithdrawal(AppWithdrawal appWithdrawal) {
        return appWithdrawalMapper.updateAppWithdrawal(appWithdrawal);
    }

    /**
     * 删除提现记录对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteAppWithdrawalByIds(String ids) {
        return appWithdrawalMapper.deleteAppWithdrawalByIds(Convert.toStrArray(ids));
    }


    @Override
//    @Transactional
    public ServerResponse<List<JSONObject>> addAppCashwithdrawal(String money, Long userId) {

        // TODO Auto-generated method stub
        log.info("新增提现记录，用户Id={}，提现金额={}，提现时间={}", userId, money, new Date());

        //redis锁-时间（2分钟）
        long startTimes = System.currentTimeMillis() + 1000 * 120;

        String redisKey = userId + "addAppCashwithdrawal";
        //获取锁
        if (!redisLockService.lock(redisKey, startTimes + "")) {
            log.info("提现操作频繁，用户Id={}，提现金额={}，记录时间={}", userId, money, new Date());
            return ServerResponse.createByErrorMessage("您操作太频繁了，稍后再试吧");
        }
        //判断防止可提现金额减为负数
        AppUser user = appUserService.selectAppUserBybalance(userId);
        if (user != null) {
            if (user.getEnable() == 0) {//禁用
                redisLockService.unlock(redisKey, null);
                return ServerResponse.createByErrorMessage("禁止提现");
            } else if (StringUtils.isEmpty(user.getAlipayAccount()) || StringUtils.isEmpty(user.getUserRealName())) {
                redisLockService.unlock(redisKey, null);
                return ServerResponse.createByErrorMessage("您不能提现请完善支付宝账号/真实姓名！");
            } else {
                //查询用户是否是黑名单用户
                /*if(iSyBlacklistService.userCheck(user.getUserId(),user.getSuperInviteCode())){
                    return ServerResponse.createByErrorMessage("您不能进行提现！如果想提现请联系客服。");
                }*/
                //用户提现余额和用户的余额做比较小于就提示余额不足
                if (user.getBalance().compareTo(BigDecimalUtils.Format(money)) < 0) {
                    redisLockService.unlock(redisKey, null);
                    log.info("新增提现记录余额不足，用户Id={}，用户余额={}，提现金额={}，提现时间={}", userId, user.getBalance(), money, new Date());
                    return ServerResponse.createByErrorMessage("可提现余额不足");
                } else {
                    AppWithdrawal appWithdrawal = new AppWithdrawal();
                    //如果是是黑名单用户直接新增一条拒绝的提现记录
                    if (iSyBlacklistService.userCheck(user.getUserId(), user.getSuperInviteCode())) {
                        appWithdrawal.setRefuseReason("黑名单用户");
                    }
                    appWithdrawal.setWithdrawalType(1);
                    appWithdrawal.setUserId(userId);
                    appWithdrawal.setWechatId(user.getWechatUnionid());
                    appWithdrawal.setWechatNickname(user.getWechatNickname());
                    Long times = System.currentTimeMillis();
                    appWithdrawal.setDeviceName(times.toString() + userId);
                    appWithdrawal.setApplicantScore(NumberUtils.toInt(money));//积分
                    appWithdrawal.setApplicantStatus(1);//处理状态：1，未处理；2，已处理；3，已拒绝
                    //appWithdrawal.setProcessingResults(processingResults);//处理结果（成功或者失败）
                    appWithdrawal.setTransferState(1);//转账状态：1，不自动转账；2，自动转账
                    appWithdrawal.setAmount(Double.valueOf(money));
                    appWithdrawal.setApplicantTime(System.currentTimeMillis());
                    appWithdrawal.setAlipayAccount(user.getAlipayAccount());
                    appWithdrawal.setPhoneNumber(user.getAlipayPhoneNumber());
                    appWithdrawal.setUserRealName(user.getUserRealName());
                    int i = insertAppWithdrawal(appWithdrawal);

                    QueryWrapper queryWrapper = new QueryWrapper();
                    queryWrapper.eq("device_name", times.toString() + userId);
                    List<AppWithdrawal> list = appWithdrawalMapper.selectList(queryWrapper);

                    if (list != null && list.size() > 0) {
                        if (i > 0) {
                            log.info("新增用户提现记录成功,用户id={}，提现金额={}，记录时间={}", userId, money, new Date());

                            BigDecimal beforeBalance = user.getBalance();
                            //减用户余额
                            int i2 = appUserService.updateAppUserbalance(userId, BigDecimalUtils.Format(money));
                            if (i2 > 0) {
                                log.info("修改用户余额成功,用户id={}，提现金额={}，余额剩余={}，记录时间={}", userId, money, user.getBalance().subtract(BigDecimalUtils.Format(money)), new Date());
                                //新增用户余额变动日志记录
                                syUserMoneyLogService.addSyUserMoneyLog(userId, beforeBalance, BigDecimalUtils.Format(money), "支付宝提现成功", 2, 1);

                            } else {
                                AppUser userOne = appUserService.selectAppUserBybalance(userId);
                                log.error("修改用户余额失败userid={},提现金额={}，余额={},记录时间={}", userId, money, userOne.getBalance(), new Date());
                            }

                            return ServerResponse.createBySuccessMessage("提现处理中");

                        } else {
                            AppUser userOne = appUserService.selectAppUserBybalance(userId);
                            log.error("新增用户提现记录失败userId={}，提现金额={}，余额={}，记录时间={}", userId, money, userOne.getBalance(), new Date());
                            return ServerResponse.createByErrorMessage("提现失败");
                        }
                    } else {
                        AppUser userOne = appUserService.selectAppUserBybalance(userId);
                        log.error("新增用户提现记录失败userId={}，提现金额={}，余额={}，记录时间={}", userId, money, userOne.getBalance(), new Date());
                        return ServerResponse.createByErrorMessage("提现失败");
                    }
                }
            }
        } else {
            return ServerResponse.createBySuccessCodeMessage(201, "用户不存在");
        }
    }

    private AppWithdrawal findAppWithdrawalByMoney(Long userId) {
        // TODO Auto-generated method stub
        return appWithdrawalMapper.findAppWithdrawalByMoneyDesc(userId);
    }

    @Override
    public ServerResponse<List<AppWithdrawal>> findAppWithdrawalByAll(Long userId, Integer pageNum,
                                                                      Integer pageSize) {
        // TODO Auto-generated method selectAppCashwithdrawalByAll
        pageNum = pageNum == null ? 0 : pageNum;
        pageSize = pageSize == null ? 20 : pageSize;
        List<AppWithdrawal> appWithdrawals =
                findAppWithdrawalByAlls(userId, pageNum, pageSize);
        if (appWithdrawals.size() > 0) {
            return ServerResponse.createBySuccess("数据获取成功", appWithdrawals);
        } else {
            return ServerResponse.createBySuccessCodeMessage(201, "暂无数据");
        }
    }

    private List<AppWithdrawal> findAppWithdrawalByAlls(Long userId, Integer pageNum, Integer pageSize) {
        // TODO Auto-generated method stub
        return appWithdrawalMapper.selectAppWithdrawalListLIMIT(userId, pageNum, pageSize);
    }

    @Override
    public HashMap<String, Object> selectAppWithdrawalBybalanceCount(Long userId, Integer i) {
        // TODO Auto-generated method selectAppCashwithdrawalBybalanceCount
        return appWithdrawalMapper.selectAppWithdrawalBybalanceCount(userId, i);
    }


    @Override
    public ServerResponse insertSelective(AppWithdrawal record) {
        int insertSelective = appWithdrawalMapper.insertAppWithdrawal(record);
        if (insertSelective == 1) {
            return ServerResponse.createBySuccessMessage("增加成功");
        }
        return ServerResponse.createByErrorMessage("增加失败");
    }

    /**
     * 查询所有提现详情
     *
     * @return
     */
    @Override
    public ServerResponse<PageInfo> selectAppWithdrawalList(Integer currentPage, Integer pageSize, Integer
            companyId, Integer withdrawalType, Long userId, Integer status, String startTime, String endTime, String keyWord,Integer transferState,String dealStartTime,String dealEndTime) {

        Long longStartTime = null;
        Long longEndTime = null;
        Long longDealStartTime = null;
        Long longDealEndTime = null;
        try {
            if (!StringUtils.isEmpty(startTime)) {
                longStartTime = DateFormatUtils.stringToLong(startTime, "yyyy-MM-dd HH:mm:ss");
            }
            if (!StringUtils.isEmpty(endTime)) {
                longEndTime = DateFormatUtils.stringToLong(endTime, "yyyy-MM-dd HH:mm:ss");
            }
            if (!StringUtils.isEmpty(dealStartTime)) {
                longDealStartTime = DateFormatUtils.stringToLong(dealStartTime, "yyyy-MM-dd HH:mm:ss");
            }
            if (!StringUtils.isEmpty(dealEndTime)) {
                longDealEndTime = DateFormatUtils.stringToLong(dealEndTime, "yyyy-MM-dd HH:mm:ss");
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }

        HashMap<String, Object> hashMap = new HashMap<String, Object>();
        hashMap.put("companyId", companyId);
        hashMap.put("withdrawalType", withdrawalType);
        hashMap.put("userId", userId);
        hashMap.put("applicantStatus", status);
        hashMap.put("longStartTime", longStartTime);
        hashMap.put("longEndTime", longEndTime);
        hashMap.put("longDealStartTime", longDealStartTime);
        hashMap.put("longDealEndTime", longDealEndTime);
        hashMap.put("keyWord", keyWord);
        hashMap.put("transferState", transferState);
        PageHelper.startPage(currentPage, pageSize);
        List withdrawalList = appWithdrawalMapper.selectAppWithdrawalList(hashMap);
        return ServerResponse.createBySuccess("查询成功", new PageInfo(withdrawalList));
    }

    /**
     * 根据用户id查询提现详情
     *
     * @param userId
     * @return
     */
    @Override
    public WithdrawalInfo selectAppWithdrawalByUserId(Long userId, Integer currentPage, Integer pageSize) {


        // 查看提现详情
        PageHelper.startPage(currentPage, pageSize);
        List<AppWithdrawal> withdrawalList = appWithdrawalMapper.selectAppWithdrawalByUserId(userId);
        if (withdrawalList == null) {
            return null;
        }
        PageInfo withdrawalListPageInfo = new PageInfo(withdrawalList);
        // 存放提现详情与订单详情
        HashMap<String, Object> map = new HashMap<>();
        WithdrawalInfo withdrawalInfo = new WithdrawalInfo();
        map.put("withdrawalListPageInfo", withdrawalListPageInfo);

        //提现总条数
        Integer withdrawalCount = appWithdrawalMapper.selectAppWithdrawalCountByUserId(userId);
        //提现总金额
        Double withdrawalAmount = appWithdrawalMapper.selectAppWithdrawalAmountByUserId(userId);
        withdrawalInfo.setTotalWithdrawalCount(withdrawalCount);
        withdrawalInfo.setTotalWithdrawalAmount(withdrawalAmount);
        // 查询根据淘宝用户id 查询商品订单详细信息
        PageHelper.startPage(currentPage, pageSize);
        List<AppOrderDetail> appOrderDetails = orderDetailMapper.findAppOrderDetailByTaobaoUserId(userId);
        PageInfo<AppOrderDetail> appOrderDetailPageInfo = new PageInfo<>(appOrderDetails);
        map.put("appOrderDetailPageInfo", appOrderDetailPageInfo);
        withdrawalInfo.setMap(map);
        //有效的订单条数
        Integer totalEffectiveItemCount = orderDetailMapper.selectTotalEffectiveItemCountByTaobaoUserId(userId);
        withdrawalInfo.setTotalEffectiveItemCount(totalEffectiveItemCount);
        // 退款总条数
        Integer totalRefundItemCount = orderDetailMapper.selectTotalRefundItemCountByTaobaoUserId(userId);
        withdrawalInfo.setTotalRefundItemCount(totalRefundItemCount);
        // 商品总佣金
        Double totalItemCommission = orderDetailMapper.selectTotalItemCommissionByTaobaoUserId(userId);
        withdrawalInfo.setTotalItemCommission(totalItemCommission);
        // 用户总佣金
        Double totalUserCommssion = userMapper.selectTotalUserCommssionByTaobaoUserId(userId);
        withdrawalInfo.setTotalUserCommssion(totalUserCommssion);
        return withdrawalInfo;
    }

    /**
     * 根据主键来更新符合条件的数据库记录,bsm_withdrawal
     *
     * @param withdrawal
     */
    @Override
    public ServerResponse insertOrUpdateSelective(AppWithdrawal withdrawal) {

        Long id = withdrawal.getId();
        // 判断数据库中是否存在提现记录
        if (id == null && id == 0) {
            int insert = appWithdrawalMapper.insertAppWithdrawal(withdrawal);
            if (insert == 1) {
                return ServerResponse.createBySuccessMessage("增加成功");
            }

            return ServerResponse.createByErrorMessage("增加失败");
        }
        int update = appWithdrawalMapper.updateAppWithdrawal(withdrawal);
        if (update == 1) {
            return ServerResponse.createBySuccessMessage("修改成功");
        }

        return ServerResponse.createByErrorMessage("修改失败");
    }


    /**
     * 根据条件模糊查询提现详情
     *
     * @param applicantStatus
     * @param startTime
     * @param endTime
     * @param keyWord
     * @return
     */
    @Override
    public ServerResponse<PageInfo> selectAppWithdrawalListByKeyWord(Integer applicantStatus, String
            startTime, String endTime, String keyWord,
                                                                     Integer currentPage, Integer pageSize, Integer companyId) {

        Long longStartTime = null;
        Long longEndTime = null;
        try {
            if (!StringUtils.isEmpty(startTime)) {
                longStartTime = DateFormatUtils.stringToLong(startTime, "yyyy-MM-dd HH:mm:ss");
            }
            if (!StringUtils.isEmpty(endTime)) {
                longEndTime = DateFormatUtils.stringToLong(endTime, "yyyy-MM-dd HH:mm:ss");
            }

        } catch (ParseException e) {
            e.printStackTrace();
        }
        AppCompany appCompany = appCompanyService.selectAppCompanyById(companyId);
        if (appCompany.getType() == 1) {
            companyId = -1;
        }

        PageHelper.startPage(currentPage, pageSize);
        List<AppWithdrawal> withdrawals = appWithdrawalMapper.selectAppWithdrawalListByKeyWord(applicantStatus, longStartTime, longEndTime, keyWord, companyId, null);
        if (withdrawals == null) {
            ServerResponse.createByErrorMessage("查询失败");
        }
        return ServerResponse.createBySuccess("查询成功", new PageInfo(withdrawals));


    }

    /**
     * 根据条件下载提现信息
     *
     * @param startTime
     * @param endTime
     * @param keyWord
     * @return
     */
    @Override
    public void downloadAppWithdrawalDetailsByKeyWord(HttpServletResponse response, Integer applicantStatus, String
            startTime, String endTime, String keyWord, Integer companyId) {
        String fileName = "提现记录";
        Long longStartTime = null;
        Long longEndTime = null;
        try {
            if (!StringUtils.isEmpty(startTime)) {
                longStartTime = DateFormatUtils.stringToLong(startTime, "yyyy-MM-dd HH:mm:ss");
            }
            if (!StringUtils.isEmpty(endTime)) {
                longEndTime = DateFormatUtils.stringToLong(endTime, "yyyy-MM-dd HH:mm:ss");
            }

        } catch (ParseException e) {
            e.printStackTrace();
        }

        AppCompany appCompany = appCompanyService.selectAppCompanyById(companyId);
        if (appCompany.getType() == 1) {
            companyId = -1;
        }

        List<AppWithdrawal> withdrawals = appWithdrawalMapper.selectAppWithdrawalListByKeyWord(applicantStatus, longStartTime, longEndTime, keyWord, companyId, null);


        String[] columnName = new String[]{"设备名称", "微信昵称", "微信号", "申请积分", "申请时间", "处理时间", "提现状态", "原因", "姓名", "支付宝账号", "手机号"};
        List<Map<String, Object>> values = Lists.newArrayList();
        String[][] content = new String[withdrawals.size()][columnName.length];
        SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        for (int i = 0; i < withdrawals.size(); i++) {
            content[i][0] = withdrawals.get(i).getDeviceName();
            content[i][1] = withdrawals.get(i).getWechatNickname();
            content[i][2] = withdrawals.get(i).getWechatId();
            content[i][3] = String.valueOf(withdrawals.get(i).getApplicantScore());
            if (withdrawals.get(i).getApplicantTime() != null) {
                content[i][4] = s.format(withdrawals.get(i).getApplicantTime().longValue());
            } else {
                content[i][4] = "";
            }
            if (withdrawals.get(i).getProcessingTime() != null) {
                content[i][5] = s.format(withdrawals.get(i).getProcessingTime().longValue());
            } else {
                content[i][5] = "";
            }
            if (withdrawals.get(i).getApplicantStatus() == 1) {
                content[i][6] = "未处理";
                content[i][7] = withdrawals.get(i).getRefuseReason();
            } else if (withdrawals.get(i).getApplicantStatus() == 2) {
                content[i][6] = "已处理";
                content[i][7] = withdrawals.get(i).getRefuseReason();
            } else if (withdrawals.get(i).getApplicantStatus() == 3) {
                content[i][6] = "已拒绝";
                content[i][7] = withdrawals.get(i).getRefuseReason();
            }
            content[i][8] = withdrawals.get(i).getUserRealName();
            content[i][9] = withdrawals.get(i).getAlipayAccount();
            content[i][10] = withdrawals.get(i).getPhoneNumber();
        }


        ExportExcelUtil.exportExcel(response, fileName, fileName, columnName, content, null);
    }

    @Override
    public int updateSum(HashMap<String, Object> hashMap) {
        transitionState(hashMap);
        return appWithdrawalMapper.updateSum(hashMap);
    }

    private void transitionState(HashMap<String, Object> hashMap) {
        MapValueHelper mapValueHelper = new MapValueHelper(hashMap);
        String transferState = mapValueHelper.getString("transferState");
        hashMap.put("transferState", Integer.valueOf(transferState));
    }

    @Override
    public int updateRefuseSum(HashMap<String, Object> hashMap) {
        transitionState(hashMap);
        return appWithdrawalMapper.updateSum(hashMap);
    }

    @Override
    public int deleteAppWithdrawalById(Long id) {
        return appWithdrawalMapper.deleteAppWithdrawalById(id);
    }

    /**
     * 提现记录查询（app轮播消息）
     *
     * @return
     */
    @Override
    public ServerResponse findAll() {
//        String userUrl = "http://qiniuimage.shengyaapp.com/Fv7u7nzglC5hCAdcSeFCCteO9KG6";

        String redisKeyStr = "app_withDrawwal_shuffling";
        List<AppWithdrawal> appWithdrawal = null;
        if (redisTemplateService.hasKey(redisKeyStr)) {
            appWithdrawal = redisTemplateService.getTByListKey(redisKeyStr, AppWithdrawal.class);
        }
        if (appWithdrawal == null || appWithdrawal.size() <= 0) {

            appWithdrawal = appWithdrawalMapper.selectAllAppWithdrawa();

            List<Long> userIds = new ArrayList<>();
            for (AppWithdrawal appWithdrawal1_ : appWithdrawal) {
                userIds.add(appWithdrawal1_.getUserId());
            }
            Map<String, String> userIcons = new HashMap<>();
            if (userIds.size() > 0) {
                QueryWrapper<AppUser> appUserQueryWrapper = new QueryWrapper<>();
                appUserQueryWrapper.in("user_id", userIds);

                List<AppUser> appUsers = appUserService.list(appUserQueryWrapper);
                if (appUsers != null && appUsers.size() > 0) {
                    for (AppUser appUser : appUsers) {
                        userIcons.put(appUser.getUserId() + "", appUser.getUserImgUrl());
                    }
                }
            }

            for (AppWithdrawal appWithdrawal1 : appWithdrawal) {
                try {
                    //String userId = String.valueOf(appWithdrawal1.getUserId());
                    Double amount = appWithdrawal1.getAmount();
//                String strAfter = userId.substring(0, 2);
//                String strBefore = userId.substring(userId.length() - 2);
                    String wechatNickname = appWithdrawal1.getWechatNickname();
                    if (wechatNickname == null) {
                        wechatNickname = "LYL";
                    }
                    String remark = new Random().nextInt(60) % (60) + 1 + "秒前" + wechatNickname + "提现了￥" + amount;
                    appWithdrawal1.setRemark(remark);
                    appWithdrawal1.setUserUrl(userIcons.get(appWithdrawal1.getUserId() + ""));
//                appWithdrawal1.setUserUrl(userUrl);
                } catch (Exception e) {
                    log.error("提现记录查询（app轮播消息）报错" + e.getMessage());
                }
            }
            if (appWithdrawal != null && appWithdrawal.size() > 0) {
                redisTemplateService.set(redisKeyStr, appWithdrawal, 60 * 3);
            }
        }
        return ServerResponse.createBySuccess("查询成功", appWithdrawal);
    }

    @Override
    public void export(HttpServletResponse response, Integer applicantStatus, String startTime, String
            endTime, String keyWord, Integer companyId, Integer withdrawalType,Integer transferState,String dealStartTime,String dealEndTime) {
        Long longStartTime = null;
        Long longEndTime = null;
        Long longDealStartTime = null;
        Long longDealEndTime = null;
        SimpleDateFormat sdf = new SimpleDateFormat("E MMM dd yyyy HH:mm:ss z", Locale.CHINA);
        try {
            if (!StringUtils.isEmpty(startTime)) {
                longStartTime = dateTransformation(startTime);
            }
            if (!StringUtils.isEmpty(endTime)) {
                longEndTime = dateTransformation(endTime);
            }
            if (!StringUtils.isEmpty(dealStartTime)) {
                longDealStartTime = DateFormatUtils.stringToLong(dealStartTime, "yyyy-MM-dd HH:mm:ss");
            }
            if (!StringUtils.isEmpty(dealEndTime)) {
                longDealEndTime = DateFormatUtils.stringToLong(dealEndTime, "yyyy-MM-dd HH:mm:ss");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        AppCompany appCompany = appCompanyService.selectAppCompanyById(companyId);
        if (appCompany.getType() == 1) {
            companyId = -1;
        }
        HashMap<String, Object> map = new HashMap();
        map.put("applicantStatus", applicantStatus);
        map.put("longStartTime", longStartTime);
        map.put("longEndTime", longEndTime);
        map.put("longDealStartTime", longDealStartTime);
        map.put("longDealEndTime", longDealEndTime);
        map.put("keyWord", keyWord);
        map.put("companyId", companyId);
        if(applicantStatus != null){
            if(withdrawalType == 1 && applicantStatus == 1){
                map.put("transferState", 1);
            }else if(withdrawalType == 1 && applicantStatus == 2) {
                map.put("transferState", transferState);
            }
        }
        map.put("withdrawalType", withdrawalType);
        List<AppWithdrawal> appWithdrawals = appWithdrawalMapper.selectAppWithdrawalList(map);
        List<SyBlacklist> syBlacklists = iSyBlacklistService.selectAllSyBlacklist();
        Iterator<AppWithdrawal> iterator = appWithdrawals.iterator();
        //移除黑名单用户以及用户余额为负数的用户
        if(withdrawalType == 1 && applicantStatus == 1){
            while (iterator.hasNext()) {
                AppWithdrawal withdrawal = iterator.next();
                for (SyBlacklist syBlacklist : syBlacklists) {
                    if (syBlacklist.getUserId().longValue() == withdrawal.getUserId().longValue() || withdrawal.getAbnormalAmount() == 1) {
                        iterator.remove();
                        break;
                    }
                }
            }
        }

        List<AppWithdrawalExportVo> appWithdrawalExportVos = JSONArray.parseArray(JSONArray.toJSONString(appWithdrawals), AppWithdrawalExportVo.class);
        EasyPoiUtils.exportExcel(appWithdrawalExportVos, "提现记录", "提现记录", AppWithdrawalExportVo.class, EasyPoiStyleUtils.class, "提现记录.xls", response);


    }

    @Override
    public List<AppWithdrawalOfMode> importExcel(HttpServletResponse response, MultipartFile file) {
        try {
            ImportParams importParams = new ImportParams();
            importParams.setNeedVerfiy(true);
            IExcelVerifyHandler<AppWithdrawalOfMode> handler = new ImportAppWithdrawalHandler();
            importParams.setVerifyHandler(handler);
            ExcelImportResult<AppWithdrawalOfMode> result = ExcelImportUtil.importExcelMore(file.getInputStream(), AppWithdrawalOfMode.class, importParams);
            List<AppWithdrawalOfMode> failAppWithdrawalList = result.getFailList();
            List<AppWithdrawalOfMode> appWithdrawalList = result.getList();
            for (AppWithdrawalOfMode appWithdrawal : appWithdrawalList) {
                int i = appWithdrawalMapper.importUpdateStatus(appWithdrawal);
                if (i <= 0) {
                    appWithdrawal.setErrorMsg("已处理/未变动");
                } else {
                    try {
                        //查询用户id
                        AppWithdrawal newAppWithdrawal = this.getById(appWithdrawal.getId());
                        int newsType = 0;
                        if (appWithdrawal.getApplicantStatus() == 3) {
                            //获取用户账户
                            SyUserMoney syUserMoney = iSyUserMoneyService.selectByUserId(newAppWithdrawal.getUserId());
                            //变动前可用余额
                            BigDecimal beforeBalance = syUserMoney.getCashBalanceAmount();
                            //给用户加钱
                            int i1 = appUserService.updateAppUseraddbalance(newAppWithdrawal.getUserId(), BigDecimalUtils.Format(newAppWithdrawal.getAmount()));
                            log.info("提现导入加回用户余额结果{}==用户id{}==金额{}", i1, newAppWithdrawal.getUserId(), newAppWithdrawal.getAmount());

                            //新增用户余额变动日志记录
                            syUserMoneyLogService.addSyUserMoneyLog(newAppWithdrawal.getUserId(), beforeBalance, BigDecimalUtils.Format(newAppWithdrawal.getAmount()), "支付宝提现失败", 2, 0);

                            newsType = NewsEnumLog.NEWS_CASH_FAIL.getNewsType();
                        } else if (appWithdrawal.getApplicantStatus() == 2) {
                            newsType = NewsEnumLog.NEWS_CASH_SUCC.getNewsType();
                            try {
                                //公众号推送到账消息
                                String amount1 = appWithdrawal.getAmount() + "元";
                                AppUser appUser = appUserService.selectAppUserByUserId(newAppWithdrawal.getUserId());
                                ServerResponse<String> result1 = iAppWxWithdrawalService.sendCashMessage(appUser, "30001", appUser.getWechatNickname(), DateFormatUtils.getCurrentDate(), amount1, "支付宝");
                                log.info("公众号发消息返回结果{}", JSONObject.toJSONString(result1));
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                        iAppNewsLogService.newsType(newAppWithdrawal.getUserId(),
                                newsType,
                                BigDecimalUtils.Format(appWithdrawal.getAmount()), appWithdrawal.getAmount().toString());

                    } catch (Exception e) {
                        log.info("导入提现成功加日志异常{}", e.getMessage());
                    }
                    appWithdrawal.setErrorMsg("成功");
                }
                log.info("提现导入修改状态是否成功{}提现对象信息{}", i, JSONObject.toJSONString(appWithdrawal));
            }
            /*Workbook workbook = result.getWorkbook();
            Workbook failWorkbook = result.getFailWorkbook();
            Workbook workbook1 = new Workbook() {
            }*/

            //EasyPoiUtils.exportExcel(failAppWithdrawalList, "提现记录", "提现记录", AppWithdrawalOfMode.class, null, "提现记录.xls", response);
            //EasyPoiUtils.downLoadExcel("提现记录失败数据",response,result.getFailWorkbook());
            /*FileOutputStream fos = new FileOutputStream("D:提现失败数据.xlsx");
            result.getFailWorkbook().write(fos);
            fos.close();*/
            List newList = new ArrayList();
            newList.addAll(appWithdrawalList);
            newList.addAll(failAppWithdrawalList);
            return newList;
        } catch (Exception e) {
            e.printStackTrace();
            log.info("导入提现记录异常{}", e.getMessage());
        }
        return new ArrayList<>();
    }

    @Override
    public List<AppWithdrawal> selectByUserIdAndAmount(Long userId, Double amount, Integer status) {
        return appWithdrawalMapper.selectByUserIdAndAmount(userId, amount, status);
    }

    @Override
    public Double statisticsAmount(Integer companyId,Integer flag) {
        return appWithdrawalMapper.statisticsAmount(companyId,flag);
    }

    @Override
    public ServerResponse<PageInfo> findUserGetMoneyDetails(int currentPage, int pageSize, Long userId) {
        // 查看提现详情
        PageHelper.startPage(currentPage, pageSize);
        List<AppWithdrawal> withdrawalList = appWithdrawalMapper.selectAppWithdrawalByUserId(userId);
        return ServerResponse.createBySuccess("查找成功", new PageInfo(withdrawalList));
    }

    /**
     * 支付宝提现，实时到账
     *
     * @param money
     * @param userId
     * @return
     */
    @Override
    @Transactional
    public ServerResponse<List<JSONObject>> withdrawalsRecordToAliPay(String money, Long userId) {
        // TODO Auto-generated method stub
        log.info("支付宝提现，用户Id={}，提现金额={}，提现时间={}", userId, money, new Date());
        //=========校验是否购买过商品，免单不算
        Integer orderCheck = appUserOrderService.getOrderCountNumber(userId);
        if(Double.valueOf(money)>0.36){
            if(orderCheck == 0){
                log.info("用户除去免单未购买",userId);
                return ServerResponse.createByErrorMessage("您还没有订单，购买后可提现！");
            }
        }

        //redis锁-时间 获取当天结束时间戳
        long startTimes = DateUtils.getTimesnight().getTime();

        String redisKey = "user_withdrawals_to_alipay_" + userId;
        //获取锁
        if (!redisLockService.lock(redisKey, startTimes + "")) {
            log.info("提现操作频繁，用户Id={}，提现金额={}，记录时间={}", userId, money, new Date());
            return ServerResponse.createByErrorMessage("今天已经提过现了，明天再来吧");
        }

        //判断 id不为空
        if (userId != null) {
            //=======每天提现一次
            Integer  withdrawalCount= appWithdrawalMapper.selectAppWithdrawalListOne(userId);
            if(withdrawalCount != null && withdrawalCount >= 1){
                return ServerResponse.createByErrorMessage("今天已经提过现了，明天再来吧");
            }

            AppUser user = appUserService.selectAppUserBybalance(userId);
            if (user != null) {
                if (user.getEnable() == 0) {//禁用
                    redisLockService.unlock(redisKey, null);
                    return ServerResponse.createByErrorMessage("禁止提现");
                } else if (StringUtils.isEmpty(user.getAlipayAccount()) || StringUtils.isEmpty(user.getUserRealName())) {
                    redisLockService.unlock(redisKey, null);
                    return ServerResponse.createByErrorMessage("您不能提现请完善支付宝账号/真实姓名！");
                } else {
                    //用户提现余额和用户的余额做比较小于就提示余额不足
                    if (user.getBalance().compareTo(BigDecimalUtils.Format(money)) < 0) {
                        redisLockService.unlock(redisKey, null);
                        log.info("支付宝提现，用户Id={}，用户余额={}，提现金额={}，提现时间={}", userId, user.getBalance(), money, new Date());
                        return ServerResponse.createByErrorMessage("可提现余额不足");
                    } else {
                        AppWithdrawal appWithdrawal = new AppWithdrawal();
                        //黑名单用户禁止提现，联系客服
                        if (iSyBlacklistService.userCheck(user.getUserId(), user.getSuperInviteCode())) {
                            return ServerResponse.createByErrorMessage("提现排队中，请联系客服");
                        }
                        //插入记录
                        appWithdrawal.setWithdrawalType(1);//1支付宝提现
                        appWithdrawal.setUserId(userId);
                        appWithdrawal.setWechatId(user.getWechatUnionid());
                        appWithdrawal.setWechatNickname(user.getWechatNickname());
                        Long times = System.currentTimeMillis();
                        String deviceName = userId +"_"+ times.toString();
                        appWithdrawal.setDeviceName(deviceName);//userId_times
                        appWithdrawal.setApplicantStatus(1);//处理状态：1，未处理；2，已处理；3，已拒绝
                        if(Double.valueOf(money) >= 100){
                            appWithdrawal.setTransferState(1);//转账状态：1，不自动转账；2，自动转账
                        }else {
                            appWithdrawal.setTransferState(2);//转账状态：1，不自动转账；2，自动转账
                        }
                        appWithdrawal.setAmount(Double.valueOf(money));
                        appWithdrawal.setApplicantTime(System.currentTimeMillis());
                        appWithdrawal.setAlipayAccount(user.getAlipayAccount());
                        appWithdrawal.setPhoneNumber(user.getAlipayPhoneNumber());
                        appWithdrawal.setUserRealName(user.getUserRealName());
                        int insertStatus = insertAppWithdrawal(appWithdrawal);

                        QueryWrapper queryWrapper = new QueryWrapper();
                        queryWrapper.eq("device_name", deviceName);
                        List<AppWithdrawal> list = appWithdrawalMapper.selectList(queryWrapper);
                        if(insertStatus > 0 && list != null && list.size() >0){
                            //先扣钱，再去转账
                            int loseMoneyStatus = appUserService.updateAppUserbalance(userId, BigDecimalUtils.Format(money));
                            if (loseMoneyStatus > 0) {
                                log.info("修改用户余额成功,userId={}，提现金额={}，余额剩余={}，记录时间={}", userId, money, user.getBalance().subtract(BigDecimalUtils.Format(money)), new Date());
                                //新增用户余额变动日志记录
                                BigDecimal beforeBalance = user.getBalance();
                                syUserMoneyLogService.addSyUserMoneyLog(userId, beforeBalance, BigDecimalUtils.Format(money), "支付宝提现", 2, 1);
                                if(list.get(0).getTransferState() == 2){
                                    //去支付
                                    try{
                                        this.toAlipay(deviceName,user.getAlipayAccount(),user.getUserRealName(),user.getUserId(),money);
                                    }catch (Exception e){
                                        e.printStackTrace();
                                        log.info("支付异常user{}money{}time{}",userId,money,new Date());
                                    }
                                }
                            }
                        }else {
                            return ServerResponse.createByErrorMessage("网络拥堵，请稍后再试");
                        }

                        return ServerResponse.createBySuccessMessage("提现处理中");
                    }
                }
            } else {
                return ServerResponse.createBySuccessCodeMessage(201, "用户不存在");
            }
        }
        return ServerResponse.createBySuccessCodeMessage(201, "用户不存在");
    }

    @Override
    public Integer statisticsPeopleAmount(Integer companyId, Integer flag) {
        return appWithdrawalMapper.statisticsPeopleAmount(companyId,flag);
    }

    @Override
    public Integer statisticsAmountNum(Integer companyId, Integer applicantStatus, Integer type, Long startDate, Long endDate) {
        return appWithdrawalMapper.statisticsAmountNum(companyId,applicantStatus,type,startDate,endDate);
    }

    @Override
    public Double statisticsAmountMoney(Integer companyId, Integer applicantStatus, Integer type, Long startDate, Long endDate) {
        return appWithdrawalMapper.statisticsAmountMoney(companyId,applicantStatus,type,startDate,endDate);
    }

    @Override
    public Double sqjdWithdrawal() {
        return appWithdrawalMapper.sqjdWithdrawal();
    }

    @Override
    public Double withdrawalAllMoney(Integer type) {
        return appWithdrawalMapper.withdrawalAllMoney(type);
    }

    @Override
    public Map<String, Object> withdrawalCommision(Integer type) {
        return appWithdrawalMapper.withdrawalCommision(type);
    }

    @Override
    public Double sqjdWithdrawalCommision() {
        return appWithdrawalMapper.sqjdWithdrawalCommision();
    }

    @Override
    public Map<String, Object> withdrawalResultCommision(Integer type, Integer flag) {
        return appWithdrawalMapper.withdrawalResultCommision(type,flag);
    }

	@Override
	public List<String> selectUserIdList() {
		return appWithdrawalMapper.selectUserIdList();
	}

	//去转账
    private void toAlipay(String deviceName,String alipayAccount ,String userRealName, Long userId, String money) {

        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("device_name", deviceName);
        List<AppWithdrawal> list = appWithdrawalMapper.selectList(queryWrapper);
        //构建对象
        AppWithdrawal withdrawal = new AppWithdrawal();
        if(list != null && list.size() == 1 && list.get(0).getApplicantStatus() == 1 && list.get(0).getTransferState() == 2){
            AlipayFundTransToaccountTransferResponse response = iAlipayService.payUserToAlipay(alipayAccount,userRealName,BigDecimalUtils.Format(money),userId);
            if (response != null && response.isSuccess() && response.getPayDate() != null
                    && RegUtils.getreGex(response.getBody(), "\"code\":\"10000\",\"msg\":\"Success\"") != null) {
                //修改记录
                withdrawal.setId(list.get(0).getId());
                withdrawal.setApplicantStatus(2);
                withdrawal.setProcessingResults("成功");
                withdrawal.setRemark("省鸭App提现实时到账");
                withdrawal.setPartnerTradeNo(response.getOutBizNo());
                try{
                    withdrawal.setRemark(response.getOrderId());
                    withdrawal.setProcessingTime(DateFormatUtils.convertTimeToLong(response.getPayDate()));
                }catch (Exception e){
                    withdrawal.setProcessingTime(new Date().getTime());
                }
                int i3 = updateAppWithdrawal(withdrawal);
                //提现成功消息入库
                iAppNewsLogService.newsType(userId,
                        NewsEnumLog.NEWS_CASH_SUCC.getNewsType(),
                        BigDecimalUtils.Format(money), money);
                if (i3 > 0) {
                    log.info("修改提现状态成功userId{}money{}time{}", userId,money,new Date());
                } else {
                    log.error("修改提现状态失败userId{}money{}time{}", userId,money,new Date());
                }
            } else if(response != null && ("20000".equals(response.getCode()) || "SYSTEM_ERROR".equalsIgnoreCase(response.getMsg()))){
                //异常状态 20000服务不可用，20001权限不足，人工核对
                log.info("支付宝支付服务异常userId{},money{}", userId,money);
                withdrawal.setId(list.get(0).getId());
                withdrawal.setRemark("服务异常，需人工审核处理");
                withdrawal.setRefuseReason(response.getSubMsg());
                int i = updateAppWithdrawal(withdrawal);
            }else if(response != null && (response.getMsg().equalsIgnoreCase("PAYER_BALANCE_NOT_ENOUGH") || response.getSubMsg().equals("付款方余额不足"))){
                log.info("支付宝支付余额不足userId{},money{}", userId,money);
                withdrawal.setId(list.get(0).getId());
                withdrawal.setRemark("支付异常，需人工审核处理");
                withdrawal.setTransferState(1);
                int i = updateAppWithdrawal(withdrawal);
            }else{
                //转账失败
                withdrawal.setId(list.get(0).getId());
                withdrawal.setApplicantStatus(3);
                withdrawal.setProcessingResults("失败");
                if(response!=null){
                    withdrawal.setRemark("省鸭App提现实时到账");
                    withdrawal.setPartnerTradeNo(response.getOrderId());
                    withdrawal.setRefuseReason(response.getSubMsg());
                }
                withdrawal.setProcessingTime(System.currentTimeMillis());
                int updateWithdrawalStatus = updateAppWithdrawal(withdrawal);
                if(updateWithdrawalStatus > 0){
                    redisLockService.unlock("user_withdrawals_to_alipay_"+userId,null);
                    //转账失败给用户加钱
                    int i2 = appUserService.updateAppUseraddbalance(userId, BigDecimalUtils.Format(money));
                    if (i2 > 0) {
                        //消息入库
                        iAppNewsLogService.newsType(userId,
                                NewsEnumLog.NEWS_CASH_FAIL.getNewsType(),
                                BigDecimalUtils.Format(money));
                    }
                }
            }
        }else {
            log.error("支付宝支付失败,userId={},提现金额={}，记录时间={}", userId, money, new Date());
        }

    }

    /**
     * Thu Aug 01 2019 16:36:50 GMT 0800(中国标准时间)转成
     * Thu Aug 01 2019 16:36:50 GMT+0800
     *
     * @param str
     * @return 时间戳
     */
    private Long dateTransformation(String str) {
        str = str.substring(0, str.lastIndexOf(" ("));
        StringBuilder sBuilder = new StringBuilder(str);
        int i = str.lastIndexOf(" ");
        str = sBuilder.replace(i, i + 1, "+").toString();
        return new Date(str).getTime();
    }
}
